package com.common.interceptor;

import java.util.HashSet;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.util.UrlPathHelper;

/**
 * Security Interceptor <br/>
 * 
 */
public class SecurityInterceptor extends HandlerInterceptorAdapter {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private UrlPathHelper urlPathHelper = new UrlPathHelper();

	private PathMatcher pathMatcher = new AntPathMatcher();

	private Set<String> excludes = new HashSet<String>();

	public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
		this.urlPathHelper = urlPathHelper;
	}

	public void setPathMatcher(PathMatcher pathMatcher) {
		this.pathMatcher = pathMatcher;
	}

	public void setExcludes(Set<String> excludes) {
		this.excludes = excludes;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		System.out.println("SecurityInterceptor : preHandle");		
		
		urlPathHelper.getLookupPathForRequest(request);
		// // 세션이 필요한 지 검사
		// if (isExcluded(excludes, uri))
		// return true;
		//
		// HttpSession session = request.getSession();
		// UserSession userSession = (UserSession) session.getAttribute(SnsConstants.SESSION);
		// if (userSession == null) {
		// logger.debug("url <{}>", request.getRequestURI());
		// throw new UnauthorizedException(SnsResultCode.UNAUTHORIZED_ERROR, "로그인이 필요합니다.");
		// }
		//
		// checkDevice(request, session, userSession);
		return true;
	}

	// private final void checkDevice(HttpServletRequest request, HttpSession session, UserSession
	// userSession) throws Exception {
	// try {
	// TbUserDevice userDevice = userService.getUserDevice(userSession.getUserDevice());
	// logger.info("session.id <{}>, db.id <{}>", new String[] { session.getId(), userDevice == null
	// ? "_EMPTY_" : userDevice.getSession_id() });
	// if (userDevice == null || !compareSessionId(userDevice.getSession_id(), session.getId())) {
	// session.invalidate();
	// throw new UnauthorizedException(SnsResultCode.UNAUTHORIZED_ERROR, "로그인이 필요합니다.");
	// }
	// } catch (Exception e) {
	// if (session != null) {
	// RequestContext context = (RequestContext) request.getAttribute(SnsConstants.REQUEST_CONTEXT);
	// if (context.isDebug())
	// logger.error("Message <{}>", e.getMessage(), e);
	// }
	// if (e instanceof NullPointerException || e instanceof RuntimeException)
	// throw new UnauthorizedException(SnsResultCode.UNAUTHORIZED_ERROR, "로그인이 필요합니다.");
	// else
	// throw e;
	// }
	// }

	/**
	 * URL 매핑 여부를 확인한다.
	 * 
	 * @param urlMappings
	 *        URL 매핑 리스트
	 * @param path
	 *        Lookup path
	 * @return true or false
	 */
	protected boolean isExcluded(Set<String> urlMappings, final String path) {
		if (!urlMappings.isEmpty()) {
			if (urlMappings.contains(path)) {
				return true;
			}
			for (final String urlMapping : urlMappings) {
				if (pathMatcher.match(urlMapping, path)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 데이터베이스에 저장되어 있는 세션ID와 비교하여 동일한 지 검사
	 * 
	 * @param stdSessionId
	 * @param sessionId
	 * @return
	 */
	private final boolean compareSessionId(String stdSessionId, String sessionId) {
		boolean b = false;
		if (sessionId != null && sessionId.indexOf('!') > 0) {
			sessionId = sessionId.substring(0, sessionId.indexOf('!'));
		}
		if (stdSessionId != null && stdSessionId.equals(sessionId)) {
			b = true;
		}
		return b;
	}

}
